/*
 * periodic.h
 *
 * Copyright 2011 Pieter Agten
 *
 * This file is part of Yarf.
 *
 * Yarf is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Yarf is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Yarf.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file   periodic.h
 * @author Pieter Agten (pieter.agten@gmail.com)
 * @date   30 okt 2011
 * @brief  The periodic scheduler allows tasks to be executed at periodic 
 *         intervals.
 */

#ifndef PERIODIC_H_
#define PERIODIC_H_

/**
 * Task that can be scheduled by the periodic scheduler.
 */
struct periodic_task {
  void (*f)(void);            /**< Pointer to the function to be executed when this periodic task needs to run. */
  unsigned long ms_periodic;  /**< Number of milliseconds in between the periodic executions of this task. */
  unsigned long ms_remaining; /**< Number of milliseconds remaining before this task needs to be executed. */
  struct periodic_task *next; /**< Pointer to the next task in the linked list of tasks to execute. */
};

/**
 * Task that can be scheduled by the periodic scheduler.
 */
typedef struct periodic_task periodic_task_t;

/**
 * Initializes the periodic scheduler.
 */
void periodic_init(void);

/**
 * Initializes a periodic task to execute a given function at constant intervals
 * of a given number of milliseconds.
 * 
 * @param task  pointer to the periodic task structure to initialize
 * @param f     pointer to the function to execute when the periodic task needs to run
 * @param ms    number of milliseconds in between the periodic executions of the task
 * 
 * @note This only initializes a periodic task structure but does not add it to
 *       periodic scheduler's list of periodic tasks to execute.
 * @see periodic_add
 */
void periodic_task_set(periodic_task_t *task, void (*f)(void), unsigned long ms);

/**
 * Adds a periodic task to the list of tasks to execute. After calling this
 * function for a specific task, that task will be executed at its corresponding
 * interval.
 *
 * @param task  pointer to the periodic task to add
 *
 * @see periodic_task_remove
 * @see periodic_task_set
 */
void periodic_add(periodic_task_t *task);

/**
 * Removes a periodic task from the list of tasks to execute. After calling this
 * function for a specific task, that task will no longer be executed by the
 * periodic scheduler.
 *
 * @param task  pointer to the periodic task to remove
 *
 * @see periodic_task_add
 */
void periodic_remove(periodic_task_t *task);


#endif //PERIODIC_H_
